var Easygooglefont_bz = new Class({
    Implements: [Options, Events],

    options: {

    },
    /* Class constructor
     * invokes the json Api connect, only when data is recevied fontao will be loaded.
     */
    initialize: function(options) {
        this.setOptions(options);
        var $this = this;
        //global var for subsets
        this.subsets = [];
        //prepare global var for wrapper
        this.fontOptionWrap;
        this.buttonSubmit = new Element('div.tl_submit.fto-submit[text=Submit]');
        //set Fake Element for Fake Block.
        //creates a fake div that inherits the font blocks
        this.fakeinputText = new Element('div.fakeinputText');
        this.fakeinputText.inject(document.id('ctrl_webfonts'), 'before');
        this.orginalInput = document.id('ctrl_webfonts');
        this.registerItems = [];
        this.dataItems;

        //invoke itemmap
        this.itemMap();

        //create basic snippet blueprint
        this.snippet = {
            'label': new Element('span.label[text=Delete]'),
            'deleteX': new Element('span.delete[text=x]'),
            'edit': new Element('span.edit[text=Edit]'),
            'wrapper': new Element('div.snippetBlock')
        }
        this.resultWrap = new Element('select.tl_select.tl_chosen');
        new Request.JSONP({
            'url': 'https://www.googleapis.com/webfonts/v1/webfonts',
            onComplete: function(data) {
                //set the display off the inputfield to none
                this.orginalInput.addClass('invisible');
                $this.initAfterListisReady(data);
                this.registerItems.each(function(el) {
                    var str = this.helpers.converTextTo(el, 'text');
                    this.addSnippetBlock(str, {}, true);
                }, this);
            }.bind(this)
        }).send();
    },
    /* everything that should be invoked when the google data is recivied
     * @method this.chosenInit() : invokes chosen
     */
    initAfterListisReady: function(data) {
        var addButton = this.addSnippetBlock('Add', {
            'class': 'snippetBlock btn',
            'events': {
                'click': function(e) {
                    this.fontOptionWrap.toggleClass('invisible');
                }.bind(this)
            }
        });

        this.chosenInit(data);
    },
    /* Generates an Item Map for easy data handling
     * extends the global this.registerItems var.
     */
    itemMap: function() {
        var input = this.orginalInput,
            getVal = input.get('value');

        //Check if empty or not and split the string to an array.
        if(getVal != '') {
            var valToArr = getVal.split('|');
        } else {
            var valToArr = false;
        }
        if(valToArr) {
            valToArr.each(function(el) {
                this.registerItems.include(el);
            }, this);
        }
    },
    /* helper to convert the itemMap to a string
     *
     */
    itemMapToString: function() {
        return this.registerItems.join("|");
    },
    /* set the new Value to the hidden original Input field
     *
     */
    reSetValue: function() {
        var itemMapString = this.itemMapToString(),
            convertToVal = this.helpers.converTextTo(itemMapString, 'value');
        this.orginalInput.set('value', convertToVal);
    },
    /* Invokes chosen and the hole box
     * TODO cleanup the method and rename it
     */
    chosenInit: function(data) {
        // buffer Data Items
        var fontList = data.items;
        var $this = this;
        //generate font items
        this.buildOptions(fontList);
        //inject the generated item into the dom
        this.resultWrap.inject(document.id('ctrl_webfonts') ,'after');
        //init chosen
        this.fontOptionWrap = new Element('div.fontOptionWrap');
        this.fontOptionWrap.toggleClass('invisible');
        this.fontOptionWrap.inject(this.resultWrap, 'after');
        this.fontOptionWrap.grab(this.resultWrap);

        var initChosen = new Chosen(this.resultWrap);
        this.buttonSubmit.inject(this.fontOptionWrap, 'inside');
        this.buttonSubmit.addEvent('click', function() {
            //TODO Ol dirty gehaxor, have to cleanup START
            var text = $this.fontOptionWrap.getElement('select').get('value'),
                variantsActives = ($this.fontOptionWrap.getElement('.variants')) ? $this.fontOptionWrap.getElement('.variants').getChildren('input:checked'): false;

            var variantArr = [];
            if(variantsActives) {
                variantsActives.each(function(child){
                    variantArr.include($this.helpers.converTextTo(child.getNext().get('text')));
                });
            }

            if(variantArr.length > 0) {
                text += ':'+variantArr.join(',');
            }
            //TODO Ol dirty gehaxor, have to cleanup STOP
            $this.fontOptionWrap.toggleClass('invisible');
            $this.addSnippetBlock(text, false, true);
            $this.addItemToTextfield(text);
        });

        this.resultWrap.addEvent('change', function(e){
            var el = this,
                text = el.get('value');
            if($$('.fontcheckboxes')[0]) {
                $$('.fontcheckboxes').dispose();
            }
            $this.loadItemOptions(el, data);

        });
    },
    loadItemOptions: function(el, data) {
        var $this = this;
        var subsets,
            variants;
        Object.each(data.items, function(key,val) {
            if(key.family == el.get('value')) {
                subsets = key.subsets;
                variants = key.variants;
            }
        });
        //$this.generateChecklist(subsets, 'Subsets', 'subsets');
        $this.generateChecklist(variants, 'Variants', 'variants');
    },
    generateChecklist: function(obj, headline, cssClass) {
        var parentEl = new Element('fieldset.tl_checkbox_container.fontcheckboxes.'+cssClass).inject(this.buttonSubmit, 'before'),
            headline = new Element('legend[text='+headline+']').inject(parentEl),
            checkbox = new Element('input.tl_checkbox[type=checkbox]'),
            label = new Element('label'),
            br = new Element('br');

        Object.each(obj, function(el) {
            var generateId = 'ctr2_'+el.toLowerCase();
            checkbox.clone().set({
                'id': generateId
            }).inject(parentEl);
            label.clone().set({
                'for': generateId,
                text: el
            }).inject(parentEl);
            br.clone().inject(parentEl);
        }, this);
    },
    addItemToTextfield: function(text) {
        var str = this.helpers.converTextTo(text, 'value'),
            input = this.orginalInput,
            val = input.get('value');


        this.registerItems.include(str);
        if(!val.contains(str)) {
            this.reSetValue();
        }
    },
    addSnippetBlock: function(textVal, options, showButtons) {
        options = (typeOf(options) === 'object') ? options : false,
        showButtons = showButtons || false;


        //clone the snippet and set Value
        var snippet = this.snippet;
        var wrapper = snippet.wrapper.clone();
        var label = snippet.label.clone().set({'text': textVal});
        var $this = this;
        if(options) {
            wrapper.set(options);
        }
        label.inject(wrapper);
        wrapper.inject(this.fakeinputText);
        if(showButtons) {
            var deleteBtn = snippet.deleteX.clone(),
                editBtn = snippet.edit.clone();
            deleteBtn.addEvent('click', function(){
                this.getParent().dispose();
                var text = this.getParent().getFirst().get('text');
                var convertToVal = $this.helpers.converTextTo(text, 'value');
                $this.registerItems.erase(convertToVal);
                $this.reSetValue();
            });
            wrapper.adopt(label, deleteBtn);
        }
    },
    buildOptions: function(list) {
        Object.each(list, function(el) {
            var opt = new Element('option.resultItem[text='+el.family+']');
            opt.inject(this.resultWrap);
        }.bind(this));
    },
    helpers: {
        converTextTo: function(text, type) {
            var search,
                newSign;

            if(typeOf(type) === 'string') {
                switch(type) {
                    case 'value':
                        search = / /g,
                        newSign = '+';
                        break;
                    case 'text':
                        search = /\+/g,
                        newSign = ' ';
                        break;
                    default:
                        throw new Error('Sorry the type could be found.');
                }
            }

            return text.replace(search, newSign);

        }
    }
});

window.addEvent('domready', function() {
    var easyFont = new Easygooglefont_bz();
});
